﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Xml;

using MyLibrary.ThreeLayer.DataAccess.Enum;

namespace MyLibrary.ThreeLayer.Utility
{
    /// <summary>
    /// 数据库连接配置
    /// </summary>
    public class Configuration
    {
        private string _connectionString;

        public string ConnectionString
        {
            get { return _connectionString; }
        }
        private ProviderType _providerType;

        public ProviderType ProviderType
        {
            get { return _providerType; }
        }

        public Configuration(ConnectionStringSettings connectionSettings)
        {
            this._connectionString = connectionSettings.ConnectionString;
            switch (connectionSettings.ProviderName.ToLower())
            {
                case "system.data.sqlclient2005":
                    this._providerType = ProviderType.SqlServer2005;
                    break;
                case "system.data.oledb":
                    this._providerType = ProviderType.OleDb;
                    break;
                case "system.data.odbc":
                    this._providerType = ProviderType.Odbc;
                    break;
                case "system.data.oracle":
                    this._providerType = ProviderType.Oracle;
                    break;
                default:
                    throw new ArgumentException("不支持的数据库类型:" + connectionSettings.ProviderName);
            }
        }

        public Configuration(XmlNode configNode)
        {
            if (configNode == null)
                throw new ArgumentNullException("不存在指定的节点");
            this._connectionString = configNode.InnerText;
            switch (configNode.Attributes["type"].Value.ToLower())
            {
                case "sqlclient2005":
                    this._providerType = ProviderType.SqlServer2005;
                    break;
                case "oledb":
                    this._providerType = ProviderType.OleDb;
                    break;
                case "odbc":
                    this._providerType = ProviderType.Odbc;
                    break;
                case "oracle":
                    this._providerType = ProviderType.Oracle;
                    break;
                default:
                    throw new ArgumentException("不支持的数据库类型:" + connectionSettings.ProviderName);
            }
        }
    }

    /// <summary>
    /// 数据库连接配置集合
    /// </summary>
    internal class ConfigurationCollection
    {
        private Dictionary<string, Configuration> _configList = new Dictionary<string, Configuration>();
        private Configuration _defaultConfig;
        private static ConfigurationCollection _collection = null;

        public Configuration DefaultConfiguration
        {
            get
            {
                if (this._defaultConfig == null)
                {
                    if (this._configList.Count == 0)
                        return null;
                    this._defaultConfig = this._configList["default"];
                }
                return this._defaultConfig;
            }
        }

        private ConfigurationCollection()
        {
            ConnectionStringSettingsCollection connectionStrings = ConfigurationManager.ConnectionStrings;
            foreach(ConnectionStringSettings setting in connectionStrings)
                this._configList.Add(setting.Name.ToLower(),new Configuration(setting));
        }

        private ConfigurationCollection(string path, string xpath)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(path);
            XmlNodeList configList = doc.SelectNodes(xpath);
            foreach (XmlNode node in configList)
                this._configList.Add(node.Attributes["name"], new Configuration(node));
        }

        public static ConfigurationCollection GetInstance()
        {
            if (_collection == null)
                _collection = new ConfigurationCollection();
            return _collection;
        }

        public static ConfigurationCollection GetInstance(string path,string xpath)
        {
            if (_collection == null)
                _collection = new ConfigurationCollection(path, xpath);
            return _collection;
        }
    }
}
